<!DOCTYPE html>
<html>
<head>
  <!--
    If you are serving your web app in a path other than the root, change the
    href value below to reflect the base path you are serving from.

    The path provided below has to start and end with a slash "/" in order for
    it to work correctly.

    For more details:
    * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base

    This is a placeholder for base href that will be replaced by the value of
    the `--base-href` argument provided to `flutter build`.
  -->
  <base href="$FLUTTER_BASE_HREF">

  <meta charset="UTF-8">
  <meta content="IE=Edge" http-equiv="X-UA-Compatible">
  <meta name="description" content="A new Flutter project.">

  <!-- iOS meta tags & icons -->
  <meta name="mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
  <meta name="apple-mobile-web-app-title" content="example">
  <link rel="apple-touch-icon" href="icons/Icon-192.png">

  <!-- Favicon -->
  <link rel="icon" type="image/png" href="favicon.png"/>

  <title>example</title>
  <link rel="manifest" href="manifest.json">
  
  <!-- 阻止 Google Fonts 请求 - 使用 CSP
  <meta http-equiv="Content-Security-Policy" content="font-src 'self' data: blob:;"> -->
  
  <!-- 预加载字体 - 提高字体加载优先级 (web/fonts 目录会直接复制到构建根目录) -->
  <link rel="preload" href="fonts/NotoSansSC-Regular.ttf" as="font" type="font/ttf" crossorigin>
  <link rel="preload" href="fonts/Roboto-Regular.ttf" as="font" type="font/ttf" crossorigin>
  <link rel="preload" href="fonts/Roboto-Bold.ttf" as="font" type="font/ttf" crossorigin>
  
  <style>
    /* 定义字体 - 使用 font-display: swap 防止文字闪烁 */
    @font-face {
      font-family: 'NotoSansSC';
      src: url('fonts/NotoSansSC-Regular.ttf') format('truetype');
      font-weight: 400;
      font-style: normal;
      font-display: swap; /* 先显示系统字体，字体加载完后再切换 */
    }
    
    @font-face {
      font-family: 'Roboto';
      src: url('fonts/Roboto-Regular.ttf') format('truetype');
      font-weight: 400;
      font-style: normal;
      font-display: swap;
    }
    
    @font-face {
      font-family: 'Roboto';
      src: url('fonts/Roboto-Bold.ttf') format('truetype');
      font-weight: 700;
      font-style: normal;
      font-display: swap;
    }
    
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      background: linear-gradient(135deg, #0a0a0a 0%, #1a1a2e 50%, #0a0a0a 100%);
      overflow: hidden;
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    }

    #loading-container {
      position: fixed;
      top: 0;
      left: 0;
      width: 100vw;
      height: 100vh;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      z-index: 9999;
      background: linear-gradient(135deg, #0a0a0a 0%, #1a1a2e 50%, #0a0a0a 100%);
      transition: opacity 0.8s ease-out;
    }

    #loading-container.fade-out {
      opacity: 0;
      pointer-events: none;
    }

    /* 粒子背景 */
    #particles-canvas {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: 1;
    }

    /* 主加载器容器 */
    .loader-wrapper {
      position: relative;
      z-index: 2;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 40px;
    }

    /* 3D旋转环 */
    .rings-container {
      position: relative;
      width: 200px;
      height: 200px;
      perspective: 1000px;
    }

    .ring {
      position: absolute;
      top: 50%;
      left: 50%;
      transform-style: preserve-3d;
      border-radius: 50%;
      border: 3px solid transparent;
      animation: rotate3d 3s infinite linear;
    }

    /* 外环 */
    .ring-1 {
      width: 200px;
      height: 200px;
      margin: -100px 0 0 -100px;
      border-color: rgba(99, 102, 241, 0.8);
      box-shadow: 0 0 30px rgba(99, 102, 241, 0.6), inset 0 0 30px rgba(99, 102, 241, 0.3);
      animation-duration: 6s;
    }

    /* 中环 */
    .ring-2 {
      width: 160px;
      height: 160px;
      margin: -80px 0 0 -80px;
      border-color: rgba(139, 92, 246, 0.8);
      box-shadow: 0 0 30px rgba(139, 92, 246, 0.6), inset 0 0 30px rgba(139, 92, 246, 0.3);
      animation-duration: 5s;
      animation-direction: reverse;
    }

    /* 内环 */
    .ring-3 {
      width: 120px;
      height: 120px;
      margin: -60px 0 0 -60px;
      border-color: rgba(236, 72, 153, 0.8);
      box-shadow: 0 0 30px rgba(236, 72, 153, 0.6), inset 0 0 30px rgba(236, 72, 153, 0.3);
      animation-duration: 2s;
    }

    /* 中心发光球 */
    .core {
      position: absolute;
      top: 50%;
      left: 50%;
      width: 60px;
      height: 60px;
      margin: -30px 0 0 -30px;
      border-radius: 50%;
      background: radial-gradient(circle, #fff 0%, rgba(99, 102, 241, 0.8) 50%, transparent 100%);
      box-shadow: 0 0 40px rgba(99, 102, 241, 1), 0 0 60px rgba(139, 92, 246, 0.8);
      animation: pulse 2s infinite ease-in-out;
    }

    @keyframes rotate3d {
      0% {
        transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg);
      }
      100% {
        transform: rotateX(360deg) rotateY(360deg) rotateZ(360deg);
      }
    }

    @keyframes pulse {
      0%, 100% {
        transform: scale(1);
        opacity: 1;
      }
      50% {
        transform: scale(1.2);
        opacity: 0.8;
      }
    }

    /* 进度条 */
    .progress-container {
      width: 300px;
      height: 6px;
      background: rgba(255, 255, 255, 0.1);
      border-radius: 10px;
      overflow: hidden;
      position: relative;
      box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.5);
    }

    .progress-bar {
      height: 100%;
      background: linear-gradient(90deg, #6366f1, #8b5cf6, #ec4899);
      border-radius: 10px;
      width: 0%;
      box-shadow: 0 0 20px rgba(99, 102, 241, 0.8);
      position: relative;
      overflow: hidden;
      transition: width 0.3s ease-out;
    }

    .progress-bar::after {
      content: '';
      position: absolute;
      top: 0;
      left: -100%;
      width: 100%;
      height: 100%;
      background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
      animation: shimmer 1.5s infinite;
    }

    @keyframes shimmer {
      0% { left: -100%; }
      100% { left: 200%; }
    }

    /* Logo 样式 */
    .logo-container {
      margin-bottom: 30px;
      display: flex;
      align-items: center;
      justify-content: center;
      gap:0px;
      animation: fadeInDown 0.8s ease-out;
    }

    .logo-image {
      height: 320px;
      object-fit: contain;
      filter: drop-shadow(0 0 20px rgba(99, 102, 241, 0.6));
      animation: logoFloat 3s ease-in-out infinite;
    }
    
    /* 专门针对 Flutter Logo 的样式 */
    .flutter-logo {
      height: 130px;
    }

    .app-title {
      color: #fff;
      font-size: 62px;
      font-weight: 600;
      text-align: center;
      letter-spacing: 1px;
      background: linear-gradient(135deg, #6366f1, #8b5cf6, #ec4899);
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      background-clip: text;
      animation: titleGlow 2s infinite ease-in-out;
    }

    @keyframes logoFloat {
      0%, 100% {
        transform: translateY(0px) rotate(0deg);
      }
      50% {
        transform: translateY(-10px) rotate(5deg);
      }
    }

    @keyframes fadeInDown {
      from {
        opacity: 0;
        transform: translateY(-30px);
      }
      to {
        opacity: 1;
        transform: translateY(0);
      }
    }

    @keyframes titleGlow {
      0%, 100% {
        filter: drop-shadow(0 0 10px rgba(99, 102, 241, 0.5));
      }
      50% {
        filter: drop-shadow(0 0 20px rgba(139, 92, 246, 0.8));
      }
    }

    /* 加载文本 */
    .loading-text {
      color: #fff;
      font-size: 24px;
      font-weight: 600;
      text-align: center;
      margin-top: -10px;
      letter-spacing: 2px;
      text-shadow: 0 0 20px rgba(99, 102, 241, 0.8);
      animation: textGlow 2s infinite ease-in-out;
    }

    .loading-subtext {
      color: rgba(255, 255, 255, 0.6);
      font-size: 14px;
      margin-top: 10px;
      letter-spacing: 1px;
    }

    .progress-info {
      display: flex;
      justify-content: space-between;
      align-items: center;
      width: 300px;
      margin-top: 8px;
      font-size: 12px;
      color: rgba(255, 255, 255, 0.5);
    }

    .progress-percent {
      font-weight: 700;
      color: #6366f1;
      font-size: 16px;
      text-shadow: 0 0 10px rgba(99, 102, 241, 0.5);
    }

    .loading-stats {
      font-size: 14px;
      font-weight: 500;
      color: rgba(255, 255, 255, 0.7);
      letter-spacing: 0.5px;
    }

    @keyframes textGlow {
      0%, 100% {
        text-shadow: 0 0 20px rgba(99, 102, 241, 0.8), 0 0 30px rgba(139, 92, 246, 0.6);
      }
      50% {
        text-shadow: 0 0 30px rgba(99, 102, 241, 1), 0 0 40px rgba(139, 92, 246, 0.8), 0 0 50px rgba(236, 72, 153, 0.6);
      }
    }

    /* 装饰性光线 */
    .light-beam {
      position: absolute;
      width: 2px;
      height: 100px;
      background: linear-gradient(180deg, transparent, rgba(99, 102, 241, 0.8), transparent);
      animation: beam 3s infinite ease-in-out;
    }

    .light-beam:nth-child(1) {
      top: 10%;
      left: 20%;
      animation-delay: 0s;
    }

    .light-beam:nth-child(2) {
      top: 30%;
      right: 15%;
      animation-delay: 0.5s;
    }

    .light-beam:nth-child(3) {
      bottom: 20%;
      left: 30%;
      animation-delay: 1s;
    }

    .light-beam:nth-child(4) {
      bottom: 10%;
      right: 25%;
      animation-delay: 1.5s;
    }

    @keyframes beam {
      0%, 100% {
        opacity: 0;
        transform: translateY(0) scaleY(0.5);
      }
      50% {
        opacity: 1;
        transform: translateY(-20px) scaleY(1);
      }
    }
  </style>
</head>
<body>
  <!-- 加载动画容器 -->
  <div id="loading-container">
    <!-- 粒子背景 -->
    <canvas id="particles-canvas"></canvas>
    
    <!-- 装饰光束 -->
    <div class="light-beam"></div>
    <div class="light-beam"></div>
    <div class="light-beam"></div>
    <div class="light-beam"></div>
    
    <!-- 主加载器 -->
    <div class="loader-wrapper">
      <!-- Logo 和标题 -->
      <div style="display: flex; flex-direction: column; align-items: center; gap: 20px;">
        <!-- 双Logo -->
        <div class="logo-container">
          <!-- Serverpod Logo -->
          <img src="assets/images/serverpod_illustration.webp" 
               alt="Serverpod Logo" 
               class="logo-image"
               onerror="this.style.display='none'">

          <!-- Flutter Logo -->
          <img src="assets/images/flutter_illustration.png" 
               alt="Flutter Logo" 
               class="logo-image flutter-logo"
               onerror="this.style.display='none'">
        </div>
        
        <!-- 标题 -->
        <h1 class="app-title">Serverpod + Flutter Web Admin</h1>
      </div>
      
      <!-- 3D旋转环 -->
      <div class="rings-container">
        <div class="ring ring-1"></div>
        <div class="ring ring-2"></div>
        <div class="ring ring-3"></div>
        <div class="core"></div>
      </div>
      
      <!-- 进度条 -->
      <div style="display: flex; flex-direction: column; align-items: center;">
        <div class="progress-container">
          <div class="progress-bar" id="progress-bar"></div>
        </div>
        <div class="progress-info">
          <span class="progress-percent" id="progress-percent">0%</span>
          <span class="loading-stats" id="loading-stats">初始化中...</span>
        </div>
      </div>
      
      <!-- 加载文本 -->
      <div style="text-align: center;">
        <div class="loading-text">正在加载中...</div>
        <div class="loading-subtext">精彩即将呈现</div>
      </div>
    </div>
  </div>

  <!-- 粒子动画脚本 -->
  <script>
    (function() {
      const canvas = document.getElementById('particles-canvas');
      const ctx = canvas.getContext('2d');
      
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
      
      const particles = [];
      const particleCount = 80;
      
      class Particle {
        constructor() {
          this.x = Math.random() * canvas.width;
          this.y = Math.random() * canvas.height;
          this.size = Math.random() * 2 + 0.5;
          this.speedX = Math.random() * 0.5 - 0.25;
          this.speedY = Math.random() * 0.5 - 0.25;
          this.opacity = Math.random() * 0.4 + 0.6;
          this.color = ['#8b92ff', '#a78bff', '#ff6bb5'][Math.floor(Math.random() * 3)];
        }
        
        update() {
          this.x += this.speedX;
          this.y += this.speedY;
          
          if (this.x > canvas.width) this.x = 0;
          if (this.x < 0) this.x = canvas.width;
          if (this.y > canvas.height) this.y = 0;
          if (this.y < 0) this.y = canvas.height;
        }
        
        draw() {
          ctx.fillStyle = this.color;
          ctx.globalAlpha = this.opacity;
          ctx.beginPath();
          ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
          ctx.fill();
        }
      }
      
      function init() {
        for (let i = 0; i < particleCount; i++) {
          particles.push(new Particle());
        }
      }
      
      function animate() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.globalAlpha = 1;
        
        particles.forEach(particle => {
          particle.update();
          particle.draw();
        });
        
        // 绘制连线
        ctx.globalAlpha = 0.3;
        for (let i = 0; i < particles.length; i++) {
          for (let j = i + 1; j < particles.length; j++) {
            const dx = particles[i].x - particles[j].x;
            const dy = particles[i].y - particles[j].y;
            const distance = Math.sqrt(dx * dx + dy * dy);
            
            if (distance < 120) {
              ctx.strokeStyle = '#8b92ff';
              ctx.lineWidth = 0.8;
              ctx.beginPath();
              ctx.moveTo(particles[i].x, particles[i].y);
              ctx.lineTo(particles[j].x, particles[j].y);
              ctx.stroke();
            }
          }
        }
        
        requestAnimationFrame(animate);
      }
      
      init();
      animate();
      
      window.addEventListener('resize', () => {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
      });
    })();
  </script>

  <!-- 加载进度监控脚本 -->
  <script>
    (function() {
      console.log('='.repeat(60));
      console.log('🚀 Flutter Web 应用加载开始');
      console.log('='.repeat(60));
      
      const progressBar = document.getElementById('progress-bar');
      const progressPercent = document.getElementById('progress-percent');
      const loadingStats = document.getElementById('loading-stats');
      
      let currentProgress = 0;
      let targetProgress = 0;
      let totalResources = 0;
      let loadedResources = 0;
      let totalSize = 0;
      let loadedSize = 0;
      const startTime = Date.now();
      
      // 进度更新队列管理
      let lastStatusChangeTime = Date.now();
      let pendingUpdate = null;
      let isUpdating = false;
      const MIN_STATUS_DURATION = 300; // 每个状态最少显示600ms，确保可读
      
      // 更新进度条的函数（带最小显示时长控制）
      function updateProgress(progress, status) {
        const now = Date.now();
        const timeSinceLastChange = now - lastStatusChangeTime;
        
        // 如果有状态文字变化
        if (status && status !== loadingStats.textContent) {
          // 如果距离上次状态变化时间太短，延迟更新
          if (timeSinceLastChange < MIN_STATUS_DURATION && !isUpdating) {
            // 保存待更新的内容
            const delay = MIN_STATUS_DURATION - timeSinceLastChange;
            
            // 如果有待处理的更新，先取消
            if (pendingUpdate) {
              // 取消之前的待更新
            }
            
            pendingUpdate = { progress, status };
            
            // 设置延迟更新
            setTimeout(() => {
              if (pendingUpdate) {
                executeUpdate(pendingUpdate.progress, pendingUpdate.status);
                pendingUpdate = null;
              }
            }, delay);
            return;
          }
        }
        
        // 立即执行更新
        executeUpdate(progress, status);
      }
      
      // 执行实际的更新
      function executeUpdate(progress, status) {
        isUpdating = true;
        targetProgress = Math.min(progress, 95); // 最多到95%，等待Flutter真正加载完成
        
        // 平滑过渡到目标进度
        const smoothUpdate = () => {
          if (currentProgress < targetProgress) {
            currentProgress += (targetProgress - currentProgress) * 0.15;
            if (Math.abs(targetProgress - currentProgress) < 0.5) {
              currentProgress = targetProgress;
            }
            progressBar.style.width = currentProgress + '%';
            progressPercent.textContent = Math.floor(currentProgress) + '%';
            if (currentProgress < targetProgress) {
              requestAnimationFrame(smoothUpdate);
            }
          }
        };
        smoothUpdate();
        
        if (status && status !== loadingStats.textContent) {
          // 直接更新文字，无动画
          loadingStats.textContent = status;
          lastStatusChangeTime = Date.now();
        }
        
        isUpdating = false;
      }
      
      // 格式化文件大小
      function formatBytes(bytes) {
        if (bytes === 0) return '0 B';
        const k = 1024;
        const sizes = ['B', 'KB', 'MB', 'GB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];
      }
      
      // ============================================
      // 真实进度监控: 资源加载 (异步并行执行)
      // 使用 PerformanceObserver 实时监听网络请求
      // 限制在30%-60%区间，避免跳跃太快
      // ============================================
      if (window.performance && window.PerformanceObserver) {
        const observer = new PerformanceObserver((list) => {
          for (const entry of list.getEntries()) {
            if (entry.initiatorType === 'script' || entry.initiatorType === 'fetch') {
              totalResources++;
              
              // 估算已加载的资源
              if (entry.responseEnd > 0) {
                loadedResources++;
                
                // 如果有transferSize信息，累加大小
                if (entry.transferSize) {
                  loadedSize += entry.transferSize;
                  totalSize += entry.transferSize;
                }
                
                // 计算进度 - 资源加载只占30%-60%的区间（缩小范围，避免跳太快）
                const resourceRatio = loadedResources / Math.max(totalResources, 1);
                const resourceProgress = 30 + (resourceRatio * 30); // 从30%到60%
                const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
                
                let status = `加载资源中 (${loadedResources}/${totalResources})`;
                if (loadedSize > 0) {
                  status = `已加载 ${formatBytes(loadedSize)} • ${elapsed}s`;
                }
                
                // 只有当新进度大于当前进度时才更新，且不超过60%
                if (resourceProgress > currentProgress && resourceProgress <= 60) {
                  updateProgress(resourceProgress, status);
                }
              }
            }
          }
        });
        
        observer.observe({ entryTypes: ['resource'] });
      }
      
      // ============================================
      // 并行机制1: 保底定时器（防止进度卡住）
      // 只有当实际进度低于目标时才会更新
      // ============================================
      let hasStartedLoading = false;
      
      // 阶段1: 初始化（0-10%）
      setTimeout(() => {
        if (currentProgress < 10) {
          updateProgress(10, '正在初始化...');
        }
      }, 200);
      
      // 阶段2: 加载引擎（10-20%）
      setTimeout(() => {
        if (currentProgress < 20) {
          updateProgress(20, '加载引擎中...');
        }
      }, 500);
      
      // 阶段3: 加载核心模块（20-30%）
      setTimeout(() => {
        if (currentProgress < 30) {
          updateProgress(30, '加载核心模块...');
        }
      }, 900);
      
      // 资源加载会在30%-60%区间实时更新（PerformanceObserver）
      
      // 阶段4: 准备渲染（60-65%）
      setTimeout(() => {
        if (currentProgress < 65) {
          updateProgress(65, '准备渲染...');
        }
      }, 2000);
      
      // 阶段5: 初始化框架（65-75%）
      setTimeout(() => {
        if (currentProgress < 75) {
          updateProgress(75, '初始化框架...');
        }
      }, 2500);
      
      // 阶段6: 渲染界面（75-85%）
      setTimeout(() => {
        if (currentProgress < 85) {
          updateProgress(85, '渲染界面...');
        }
      }, 3000);
      
      // 阶段7: 即将完成（85-90%）
      setTimeout(() => {
        if (currentProgress < 90) {
          updateProgress(90, '即将完成...');
        }
      }, 3500);
      
      // ============================================
      // 并行机制3: 字体加载监控（独立轮询）
      // 每100ms检查一次，与其他加载过程并行
      // ============================================
      let fontsLoaded = false;
      let flutterReady = false;
      let wasmLoaded = false; // WASM 加载状态标志
      
      function checkAndHideLoader() {
        // 只有当三个条件都满足时才隐藏加载器：
        // 1. WASM 文件加载完成
        // 2. 字体加载完成
        // 3. Flutter 首帧渲染完成
        console.log(`[加载器] 检查隐藏条件 - WASM加载: ${wasmLoaded}, Flutter就绪: ${flutterReady}, 字体加载: ${fontsLoaded}`);
        
        if (wasmLoaded && flutterReady && fontsLoaded) {
          console.log('[加载器] ✅ 所有条件满足，开始隐藏加载器');
          updateProgress(100, '加载完成！');
          progressPercent.textContent = '100%';
          
          setTimeout(() => {
            const loadingContainer = document.getElementById('loading-container');
            loadingContainer.classList.add('fade-out');
            console.log('[加载器] 🎉 加载器淡出动画开始');
            setTimeout(() => {
              loadingContainer.style.display = 'none';
              console.log('[加载器] 🎉 加载器已完全隐藏，应用启动完成！');
            }, 800);
          }, 300);
        } else {
          console.log('[加载器] ⏸️ 等待条件满足...');
        }
      }
      
      // ============================================
      // 并行机制3.5: WASM 加载监控（关键修复）
      // 监控 main.dart.wasm 的实际加载状态
      // ============================================
      
      // 使用 PerformanceObserver 监控 WASM 文件加载
      if (window.performance && window.PerformanceObserver) {
        const wasmObserver = new PerformanceObserver((list) => {
          for (const entry of list.getEntries()) {
            if (entry.name.includes('main.dart.wasm') || entry.name.includes('main.dart.mjs')) {
              // console.log(`[WASM] 📦 检测到文件加载: ${entry.name.split('/').pop()}`);
              // console.log(`[WASM] 📊 大小: ${(entry.transferSize / 1024 / 1024).toFixed(2)} MB`);
              // console.log(`[WASM] ⏱️  耗时: ${(entry.duration / 1000).toFixed(2)}s`);
              
              // 检查是否加载完成
              if (entry.responseEnd > 0) {
                wasmLoaded = true;
                console.log('[WASM] ✅ WASM 文件加载完成');
                
                // WASM 加载完成后，更新进度到 70%
                if (currentProgress < 70) {
                  updateProgress(70, 'WASM 引擎加载完成');
                }
                
                checkAndHideLoader();
              }
            }
          }
        });
        
        wasmObserver.observe({ entryTypes: ['resource'] });
      }
      
      // WASM 超时保护：如果 15 秒后还没加载完成，强制标记为完成
      // （1.2MB 的文件，即使慢速网络也应该能在 15 秒内加载完）
      setTimeout(() => {
        if (!wasmLoaded) {
          console.warn('[WASM] ⏱️ WASM 加载超时(15秒)，强制标记为完成');
          wasmLoaded = true;
          checkAndHideLoader();
        }
      }, 15000);
      
      // 字体加载监控（并行执行）- 简化版，更可靠
      console.log('[字体] 🔍 开始监控字体加载...');
      if (document.fonts && document.fonts.ready) {
        console.log('[字体] 📝 Font Loading API 可用，等待字体加载完成...');
        
        // 等待所有字体加载完成
        document.fonts.ready
          .then(() => {
            console.log('[字体] ✅ 所有字体加载完成');
            fontsLoaded = true;
            // 如果当前进度已经到90%以上，显示字体加载完成状态
            if (currentProgress >= 90) {
              updateProgress(95, '字体加载完成');
            }
            checkAndHideLoader();
          })
          .catch((error) => {
            console.warn('[字体] ⚠️ 字体加载失败，继续启动应用:', error);
            fontsLoaded = true;
            checkAndHideLoader();
          });
        
        // 超时保护：最多等待 2 秒字体加载
        setTimeout(() => {
          if (!fontsLoaded) {
            console.warn('[字体] ⏱️ 字体加载超时(2秒)，强制继续');
            fontsLoaded = true;
            checkAndHideLoader();
          }
        }, 2000);
      } else {
        // 浏览器不支持 Font Loading API，直接标记为完成
        console.log('[字体] ℹ️ 浏览器不支持 Font Loading API，跳过字体检测');
        fontsLoaded = true;
      }
      
      // ============================================
      // 并行机制4: Flutter 就绪事件（异步回调）
      // 由 Flutter 引擎在首帧渲染完成后触发
      // 与其他所有机制完全并行执行
      // ============================================
      window.addEventListener('flutter-first-frame', function() {
        console.log('[Flutter] ✅ 首帧渲染完成');
        flutterReady = true;
        // Flutter 渲染完成后，更新进度到 95%
        updateProgress(95, 'Flutter 初始化完成');
        checkAndHideLoader(); // 尝试隐藏（需要同时满足 fontsLoaded 和 wasmLoaded）
      });
      
      // ============================================
      // 关键修复：延长 Flutter 超时保护时间
      // 如果 20 秒后 Flutter 还没触发 first-frame，强制标记为就绪
      // （必须给 WASM 足够的加载时间）
      // ============================================
      setTimeout(() => {
        if (!flutterReady) {
          console.warn('[Flutter] ⏱️ Flutter 初始化超时(20秒)，强制标记为就绪');
          flutterReady = true;
          checkAndHideLoader();
        }
      }, 20000);
      
      // 超时保护：如果30秒还没加载完成，强制显示高进度
      setTimeout(() => {
        if (currentProgress < 90) {
          updateProgress(90, '正在完成最后步骤...');
        }
      }, 30000);
      
    })();
  </script>

  <!-- CanvasKit 智能 CDN 降级加载策略（乐观加载模式）-->
  <script>
    (function() {
      // CDN 列表（按优先级排序）
      const CDN_SOURCES = [
        'https://unpkg.com/canvaskit-wasm@0.40.0/bin/',           // 优先使用 unpkg（通常更快）
        'https://cdn.jsdelivr.net/npm/canvaskit-wasm@0.40.0/bin/', // 备用 jsdelivr
        '/canvaskit/'                                               // 最后使用本地文件
      ];
      
      let currentCdnIndex = 0;
      let cdnSwitchCount = 0; // 防止无限循环切换
      const MAX_CDN_SWITCHES = 3;
      
      // 从 localStorage 读取上次成功的 CDN
      try {
        const savedIndex = localStorage.getItem('canvaskit_cdn_index');
        if (savedIndex !== null) {
          const index = parseInt(savedIndex, 10);
          if (index >= 0 && index < CDN_SOURCES.length) {
            currentCdnIndex = index;
            console.log(`[CanvasKit] 使用上次成功的 CDN ${index + 1}: ${CDN_SOURCES[index]}`);
          }
        }
      } catch (e) {
        // localStorage 可能被禁用，忽略错误
      }
      
      // 保存 CDN 配置到全局变量，供 Flutter 新 API 使用
      const currentCdnUrl = CDN_SOURCES[currentCdnIndex];
      window._canvasKitBaseUrl = currentCdnUrl;
      console.log(`[CanvasKit] 配置加载源: ${currentCdnUrl}`);
      
      // 监听 CanvasKit 加载错误，尝试切换 CDN
      window.addEventListener('error', function(event) {
        const target = event.target;
        
        // 检测是否是 CanvasKit 相关资源加载失败
        if (target && (target.src || target.href)) {
          const url = target.src || target.href;
          if (url.includes('canvaskit') || url.includes('skwasm')) {
            console.error('[CanvasKit] ❌ 资源加载失败:', url);
            
            // 检查是否超过最大切换次数
            if (cdnSwitchCount >= MAX_CDN_SWITCHES) {
              console.error('[CanvasKit] ❌ 超过最大切换次数，停止尝试');
              alert('应用加载失败：CanvasKit 渲染引擎无法加载。\n请检查网络连接或稍后再试。');
              return;
            }
            
            // 如果还有备用 CDN，尝试切换
            if (currentCdnIndex < CDN_SOURCES.length - 1) {
              currentCdnIndex++;
              cdnSwitchCount++;
              
              console.log(`[CanvasKit] 🔄 切换到 CDN ${currentCdnIndex + 1}/${CDN_SOURCES.length}: ${CDN_SOURCES[currentCdnIndex]}`);
              
              // 清除失败的 CDN 记录
              try {
                localStorage.removeItem('canvaskit_cdn_index');
              } catch (e) {
                // 忽略错误
              }
              
              // 延迟刷新，让用户看到提示
              setTimeout(() => {
                console.log('[CanvasKit] 刷新页面以使用新 CDN...');
                window.location.reload();
              }, 500);
            } else {
              console.error('[CanvasKit] ❌ 所有 CDN 源都已尝试，无法加载 CanvasKit');
              alert('应用加载失败：无法获取 CanvasKit 渲染引擎。\n已尝试所有可用源，请检查网络连接。');
            }
          }
        }
      }, true);
      
      // 监听 Flutter 首帧渲染完成（表示 CanvasKit 加载成功）
      window.addEventListener('flutter-first-frame', function() {
        console.log('[CanvasKit] ✅ 加载成功');
        // 保存成功的 CDN 到 localStorage
        try {
          localStorage.setItem('canvaskit_cdn_index', currentCdnIndex.toString());
          console.log(`[CanvasKit] 💾 已保存成功的 CDN 索引: ${currentCdnIndex}`);
        } catch (e) {
          // localStorage 可能被禁用，忽略错误
        }
      });
      
    })();
  </script>

  <!-- 增强版 Service Worker 注册 -->
  <script>
    (function() {
      // 开发模式下暂时禁用 Service Worker,避免缓存问题
      const isDevMode = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';
      
      if (isDevMode) {
        console.log('[App] 🔧 开发模式:禁用 Service Worker');
        // 注销所有已存在的 Service Worker
        if ('serviceWorker' in navigator) {
          navigator.serviceWorker.getRegistrations().then(registrations => {
            registrations.forEach(registration => {
              registration.unregister();
              console.log('[App] 已注销 Service Worker:', registration.scope);
            });
          });
        }
        return; // 跳过 Service Worker 注册
      }
      
      // 检查浏览器是否支持 Service Worker
      if ('serviceWorker' in navigator) {
        window.addEventListener('load', () => {
          // 注册自定义 Service Worker
          navigator.serviceWorker.register('/sw-config.js')
            .then(registration => {
              console.log('[App] Service Worker 注册成功:', registration.scope);
              
              // 检查更新
              registration.addEventListener('updatefound', () => {
                const newWorker = registration.installing;
                console.log('[App] 发现新的 Service Worker');
                
                newWorker.addEventListener('statechange', () => {
                  if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
                    // 新版本已安装，提示用户刷新
                    console.log('[App] 新版本可用，建议刷新页面');
                    // 可选：显示通知提示用户刷新
                    showUpdateNotification();
                  }
                });
              });
            })
            .catch(error => {
              console.warn('[App] Service Worker 注册失败:', error);
              // Service Worker 失败不影响应用正常运行
            });
          
          // 监听 Service Worker 消息
          navigator.serviceWorker.addEventListener('message', (event) => {
            console.log('[App] 收到 Service Worker 消息:', event.data);
            
            if (event.data.type === 'cache-cleared') {
              console.log('[App] 缓存已清除，刷新页面...');
              window.location.reload();
            }
            
            if (event.data.type === 'cache-stats') {
              console.log('[App] 缓存统计:', event.data.data);
            }
          });
        });
        
        // 提供全局方法用于缓存管理
        window.swUtils = {
          // 清除所有缓存
          clearCache: async () => {
            const registration = await navigator.serviceWorker.ready;
            registration.active.postMessage('clearCache');
          },
          
          // 获取缓存统计
          getCacheStats: async () => {
            const registration = await navigator.serviceWorker.ready;
            registration.active.postMessage('getCacheStats');
          },
          
          // 强制更新 Service Worker
          update: async () => {
            const registration = await navigator.serviceWorker.ready;
            await registration.update();
            console.log('[App] Service Worker 已更新');
          },
          
          // 卸载 Service Worker
          unregister: async () => {
            const registration = await navigator.serviceWorker.ready;
            const success = await registration.unregister();
            if (success) {
              console.log('[App] Service Worker 已卸载');
              // 清除所有缓存
              const cacheNames = await caches.keys();
              await Promise.all(cacheNames.map(name => caches.delete(name)));
              console.log('[App] 所有缓存已清除');
            }
            return success;
          },
        };
        
        // 显示更新通知（可自定义样式）
        function showUpdateNotification() {
          // 创建通知元素
          const notification = document.createElement('div');
          notification.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            background: linear-gradient(135deg, #6366f1, #8b5cf6);
            color: white;
            padding: 16px 24px;
            border-radius: 12px;
            box-shadow: 0 4px 20px rgba(99, 102, 241, 0.4);
            z-index: 10000;
            font-family: 'Segoe UI', sans-serif;
            font-size: 14px;
            display: flex;
            align-items: center;
            gap: 12px;
            animation: slideIn 0.3s ease-out;
          `;
          
          notification.innerHTML = `
            <button id="close-notification-btn" style="
              position: absolute;
              top: 8px;
              right: 8px;
              background: transparent;
              border: none;
              color: rgba(255, 255, 255, 0.7);
              cursor: pointer;
              font-size: 18px;
              padding: 0;
              width: 24px;
              height: 24px;
              display: flex;
              align-items: center;
              justify-content: center;
              transition: all 0.2s;
            " onmouseover="this.style.color='white'; this.style.transform='scale(1.1)'" 
               onmouseout="this.style.color='rgba(255, 255, 255, 0.7)'; this.style.transform='scale(1)'">
              ✕
            </button>
            <div>
              <div style="font-weight: 600; margin-bottom: 4px;">🎉 新版本可用</div>
              <div style="font-size: 12px; opacity: 0.9;">点击刷新以获取最新功能</div>
            </div>
            <button id="update-refresh-btn" style="
              background: white;
              color: #6366f1;
              border: none;
              padding: 8px 16px;
              border-radius: 6px;
              cursor: pointer;
              font-weight: 600;
              font-size: 12px;
              transition: all 0.3s ease;
            ">刷新</button>
          `;
          
          // 添加关闭按钮的点击事件
          const closeBtn = notification.querySelector('#close-notification-btn');
          closeBtn.addEventListener('click', () => {
            notification.style.animation = 'slideIn 0.3s ease-out reverse';
            setTimeout(() => notification.remove(), 300);
          });
          
          // 添加刷新按钮的点击事件
          const refreshBtn = notification.querySelector('#update-refresh-btn');
          refreshBtn.addEventListener('click', () => {
            // 禁用按钮，防止重复点击
            refreshBtn.disabled = true;
            refreshBtn.style.cursor = 'not-allowed';
            refreshBtn.style.opacity = '0.6';
            
            // 添加加载动画
            refreshBtn.innerHTML = `
              <span style="display: inline-block; animation: spin 1s linear infinite;">⟳</span>
              刷新中...
            `;
            
            // 添加旋转动画
            const spinStyle = document.createElement('style');
            spinStyle.textContent = `
              @keyframes spin {
                from { transform: rotate(0deg); }
                to { transform: rotate(360deg); }
              }
            `;
            document.head.appendChild(spinStyle);
            
            // 延迟一点点再刷新，让用户看到反馈
            setTimeout(() => {
              window.location.reload();
            }, 300);
          });
          
          // 添加动画
          const style = document.createElement('style');
          style.textContent = `
            @keyframes slideIn {
              from { transform: translateX(400px); opacity: 0; }
              to { transform: translateX(0); opacity: 1; }
            }
          `;
          document.head.appendChild(style);
          
          document.body.appendChild(notification);
          
          // 10秒后自动隐藏
          setTimeout(() => {
            notification.style.animation = 'slideIn 0.3s ease-out reverse';
            setTimeout(() => notification.remove(), 300);
          }, 10000);
        }
        
        console.log('[App] Service Worker 支持已启用');
      } else {
        console.warn('[App] 浏览器不支持 Service Worker');
      }
    })();
  </script>

  <!-- Flutter 初始化脚本 -->
  <script>
    {{flutter_js}}
  </script>
  <script>
    {{flutter_build_config}}
  </script>
  
  <script>
    // 资源加载监控脚本 - 显示所有资源的加载来源、耗时和缓存状态
    (function() {
      // console.log('%c[资源监控] 开始监控所有资源加载...', 'color: #00ff00; font-weight: bold;');
      // console.log('%c[缓存策略] Flutter Web 使用基于内容哈希的缓存策略', 'color: #00aaff; font-weight: bold;');
      // console.log('%c[缓存策略] 首次访问会下载文件，后续访问将从浏览器缓存加载（极快）', 'color: #00aaff;');
      // console.log('─'.repeat(60));
      
      let totalDownloaded = 0;
      let totalFromCache = 0;
      let downloadedSize = 0;
      
      // 监听所有资源加载
      if (window.performance && window.PerformanceObserver) {
        const observer = new PerformanceObserver((list) => {
          for (const entry of list.getEntries()) {
            // 只关注重要资源
            if (entry.name.includes('main.dart') || 
                entry.name.includes('canvaskit') || 
                entry.name.includes('skwasm') ||
                entry.initiatorType === 'script' ||
                entry.initiatorType === 'fetch') {
              
              const url = new URL(entry.name);
              const fileName = url.pathname.split('/').pop();
              
              // 判断是否从缓存加载
              const isFromCache = entry.transferSize === 0 && entry.decodedBodySize > 0;
              const fileSize = entry.transferSize > 0 
                ? (entry.transferSize / 1024 / 1024).toFixed(2) + ' MB' 
                : (isFromCache ? '💾 浏览器缓存' : '(未知)');
              
              const duration = (entry.duration / 1000).toFixed(2) + 's';
              
              // 统计
              if (isFromCache) {
                totalFromCache++;
              } else if (entry.transferSize > 0) {
                totalDownloaded++;
                downloadedSize += entry.transferSize;
              }
              
              // 判断来源
              let source = '';
              if (url.hostname === window.location.hostname) {
                source = '🏠 本地服务器 (' + url.hostname + ')';
              } else {
                source = '🌐 CDN (' + url.hostname + ')';
              }
              
              // 缓存状态标识
              const cacheStatus = isFromCache ? '💾 缓存命中' : '📥 网络下载';
              
              // console.log(`%c[资源] ${fileName}`, isFromCache ? 'color: #10b981; font-weight: bold;' : 'color: #6366f1; font-weight: bold;');
              // console.log(`  📍 来源: ${source}`);
              // console.log(`  ${isFromCache ? '💾' : '📦'} 大小: ${fileSize}`);
              // console.log(`  ⏱️  耗时: ${duration}`);
              // console.log(`  🎯 状态: ${cacheStatus}`);
              // console.log(`  🔗 完整URL: ${entry.name}`);
              // console.log('─'.repeat(60));
            }
          }
        });
        
        observer.observe({ entryTypes: ['resource'] });
        
        // 页面加载完成后显示统计信息
        window.addEventListener('load', () => {
          setTimeout(() => {
            // console.log('%c[统计信息] 资源加载统计', 'color: #f59e0b; font-weight: bold; font-size: 14px;');
            // console.log(`  📥 网络下载: ${totalDownloaded} 个文件`);
            // console.log(`  💾 缓存命中: ${totalFromCache} 个文件`);
            // console.log(`  📊 下载大小: ${(downloadedSize / 1024 / 1024).toFixed(2)} MB`);
            // console.log(`  🚀 缓存效率: ${totalFromCache > 0 ? ((totalFromCache / (totalDownloaded + totalFromCache)) * 100).toFixed(1) : 0}%`);
            // console.log('─'.repeat(60));
            
            if (totalFromCache > 0) {
              // console.log('%c✅ 浏览器缓存正常工作！二次访问速度将大幅提升！', 'color: #10b981; font-weight: bold; font-size: 14px;');
            } else {
              // console.log('%cℹ️  首次访问，正在建立缓存。下次访问将直接从缓存加载。', 'color: #3b82f6; font-weight: bold; font-size: 14px;');
            }
          }, 2000);
        });
      }
    })();
  </script>
  
  <script>
    // Flutter 引擎初始化脚本
    (function() {
      console.log('[Flutter初始化] 开始初始化...');
      
      // 等待 _flutter 对象可用
      let attempts = 0;
      const maxAttempts = 200; // 10秒超时 (50ms * 200)
      
      const checkFlutter = setInterval(function() {
        attempts++;
        
        if (typeof _flutter !== 'undefined' && _flutter.loader) {
          clearInterval(checkFlutter);
          console.log('[Flutter初始化] ✅ _flutter 对象已就绪');
          
          // 开始加载 Flutter 应用
          _flutter.loader.load({
            onEntrypointLoaded: async function(engineInitializer) {
              try {
                console.log('[Flutter初始化] 入口点已加载,初始化引擎...');
                
                // 配置引擎参数
                const engineConfig = {
                  renderer: "canvaskit",
                  canvasKitBaseUrl: window._canvasKitBaseUrl || "https://unpkg.com/canvaskit-wasm@0.40.0/bin/"
                };
                
                console.log('[Flutter初始化] 引擎配置:', engineConfig);
                
                let appRunner = await engineInitializer.initializeEngine(engineConfig);
                
                console.log('[Flutter初始化] 引擎初始化完成,运行应用...');
                await appRunner.runApp();
                console.log('[Flutter初始化] ✅ 应用启动成功！');
                
              } catch (error) {
                console.error('[Flutter初始化] ❌ 初始化失败:', error);
                alert('应用加载失败:\n' + error.message + '\n\n请查看控制台了解详情');
              }
            }
          });
        } else if (attempts >= maxAttempts) {
          clearInterval(checkFlutter);
          console.error('[Flutter初始化] ❌ 超时: _flutter 对象未就绪');
          alert('Flutter 加载超时,请刷新页面重试');
        }
      }, 50);
    })();
  </script>
</body>
</html>
